package com.mall.product.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.mall.common.page.PageData;
import com.mall.common.service.impl.CrudServiceImpl;
import com.mall.common.utils.ConvertUtils;
import com.mall.product.dao.AttrGroupDao;
import com.mall.product.dto.AttrDTO;
import com.mall.product.dto.AttrGroupDTO;
import com.mall.product.entity.AttrAttrgroupRelationEntity;
import com.mall.product.entity.AttrEntity;
import com.mall.product.entity.AttrGroupEntity;
import com.mall.product.entity.ProductAttrValueEntity;
import com.mall.product.service.AttrAttrgroupRelationService;
import com.mall.product.service.AttrGroupService;
import com.mall.product.service.AttrService;
import com.mall.product.service.ProductAttrValueService;
import com.mall.product.vo.AttrGroupRelationVo;
import com.mall.product.vo.AttrGroupWithAttrVo;
import com.mall.product.vo.SkuItemVo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 属性分组
 *
 * @author xjc xjc@163.com
 * @since 1.0.0 2022-07-17
 */
@Service
public class AttrGroupServiceImpl extends CrudServiceImpl<AttrGroupDao, AttrGroupEntity, AttrGroupDTO> implements AttrGroupService {

    @Resource
    private AttrAttrgroupRelationService attrGroupRelationService;
    @Resource
    private ProductAttrValueService ProductAttrValueService;
    @Resource
    private AttrService attrService;

    @Override
    public QueryWrapper<AttrGroupEntity> getWrapper(Map<String, Object> params){
        String id = (String)params.get("id");

        QueryWrapper<AttrGroupEntity> wrapper = new QueryWrapper<>();
        wrapper.eq(StringUtils.isNotBlank(id), "id", id);

        return wrapper;
    }


    @Override
    public PageData<AttrGroupDTO> queryPageByCatelogId(Map<String, Object> params, Long catelogId) {
        // select *  from pms_attr_group
        String key = (String) params.get("key");
        QueryWrapper<AttrGroupEntity> queryWrapper = new QueryWrapper<>();
        if (catelogId!=0)
            queryWrapper.eq("catelog_id", catelogId);
        if (key!=null&&!key.isEmpty())
            queryWrapper.and((obj)->{
                obj.eq("attr_group_id",key).or().like("attr_group_name",key);});
        IPage<AttrGroupEntity> attrGroupEntityIPage = baseDao.selectPage(getPage(params, null, false), queryWrapper);

        return getPageData(attrGroupEntityIPage, currentDtoClass());
    }

    @Override
    public List<AttrDTO> findAllRelationGrooup(Long attrGroupId) {
        List<AttrAttrgroupRelationEntity> attrAttrgroupRelationEntities = attrGroupRelationService.selectByAttrGroupId(attrGroupId);
        List<Long> ids = attrAttrgroupRelationEntities.stream().map(AttrAttrgroupRelationEntity::getAttrId).collect(Collectors.toList());
        if (ids.size()>0){
            List<AttrEntity> attrEntityList = attrService.ListByIds(ids);
            return ConvertUtils.sourceToTarget(attrEntityList, AttrDTO.class);
        }
        return new ArrayList<>();
    }

    @Override
    public AttrGroupEntity findByAttrId(Long attrId) {
       return null;
    }

    @Override
    public PageData<AttrDTO> findAllUnRelationGrooup(Map<String, Object> params,Long attrGroupId) {
        // 只能所示分类的属性
        // 只能未关联的属性
        AttrGroupEntity currentGroupEntity = baseDao.selectById(attrGroupId);
        Long catelogId = currentGroupEntity.getCatelogId();
        List<AttrGroupEntity> otherGroupList = baseDao.selectList(new QueryWrapper<AttrGroupEntity>()
                .eq("catelog_id", catelogId));
        List<Long> groupIds = otherGroupList.stream().map(AttrGroupEntity::getAttrGroupId).collect(Collectors.toList());
        // 查找关联的实体
        List<AttrAttrgroupRelationEntity> relationEntities = attrGroupRelationService.selectWithInCollection(groupIds);
//        List<AttrAttrgroupRelationEntity> unRelationEntities = attrgroupRelationService.selectWithoutInCollection(groupIds);
        // 查找已关联的属性Id
        List<Long> idList = relationEntities.stream().map(AttrAttrgroupRelationEntity::getAttrId).collect(Collectors.toList());
        // 查找不在上面集合的，本分组下的属性
        return attrService.selectWithOutInCollection(params,catelogId,idList);

    }

    @Override
    public void savaRelation(List<AttrGroupRelationVo> relationVos) {
        List<AttrAttrgroupRelationEntity> saveList = relationVos.stream().map(item -> {
            AttrAttrgroupRelationEntity relationEntity = new AttrAttrgroupRelationEntity();
            relationEntity.setAttrId(item.getAttrId());
            relationEntity.setAttrGroupId(item.getAttrGroupId());
            return relationEntity;
        }).collect(Collectors.toList());
        attrGroupRelationService.insertBatch(saveList);

    }

    @Override
    public List<AttrGroupWithAttrVo> getAttrGroupWithAttrsByCatelogId(Long catelogId) {
        // 查询关联关系
        List<AttrGroupEntity> groupEntities = baseDao.selectList(new QueryWrapper<AttrGroupEntity>().eq("catelog_id", catelogId));
        if (groupEntities.size()>0){
            List<AttrGroupWithAttrVo> result = groupEntities.stream().map(group -> {
                AttrGroupWithAttrVo withAttrVo = new AttrGroupWithAttrVo();
                BeanUtil.copyProperties(group,withAttrVo);
                List<AttrEntity> attrEntities = attrGroupRelationService.selectByAttrGroupId(group.getAttrGroupId()).stream().map(relation ->
                        attrService.selectById(relation.getAttrId())
                ).collect(Collectors.toList());
                List<AttrDTO> attrDTOS = ConvertUtils.sourceToTarget(attrEntities, AttrDTO.class);
                withAttrVo.setAttrs(attrDTOS);
                return withAttrVo;
            }).collect(Collectors.toList());
          return  result;
        }

        return null;
    }

    @Override
    public List<SkuItemVo.SpuItemAttrGroupVo> getAttrGroupWithAttrsBySpuId(Long spuId,Long catelogId) {
        QueryWrapper<AttrGroupEntity> queryWrapper = new QueryWrapper<AttrGroupEntity>().eq("catelog_id", catelogId);
        List<AttrGroupEntity> attrGroupEntities = baseDao.selectList(queryWrapper);
        List<Long> attrGroupIds = attrGroupEntities.stream().map(AttrGroupEntity::getAttrGroupId).collect(Collectors.toList());
        List<AttrAttrgroupRelationEntity> relationEntities = attrGroupRelationService.listByAttrGroupId(attrGroupIds);
        HashMap<String,List<String>> relationMap = new HashMap<>();
        relationEntities.stream().forEach(item->{
            List<String> attrIds = relationMap.getOrDefault(item.getAttrGroupId().toString(), new ArrayList<String>());
            attrIds.add(item.getAttrId().toString());
            relationMap.put(item.getAttrGroupId().toString(),attrIds);
        });
        List<ProductAttrValueEntity> productAttrValueEntities = ProductAttrValueService.queryAttrIdsBySpuId(spuId);
        Map<String, String> attrNameMap = productAttrValueEntities.stream().collect(Collectors.toMap(k -> k.getAttrId().toString(), ProductAttrValueEntity::getAttrName));
        Map<String, String> attrValueMap = productAttrValueEntities.stream().collect(Collectors.toMap(k -> k.getAttrId().toString(), ProductAttrValueEntity::getAttrValue));
        List<SkuItemVo.SpuItemAttrGroupVo> spuItemAttrGroupVos = attrGroupEntities.stream().map(group -> {
            SkuItemVo.SpuItemAttrGroupVo attrGroupVo = new SkuItemVo.SpuItemAttrGroupVo();
            attrGroupVo.setGroupName(group.getAttrGroupName());
            List<SkuItemVo.SpuBaseAttrVo> attrVos = new ArrayList<>();
            Long attrGroupId = group.getAttrGroupId();
            List<String> collectAttrIds = relationMap.get(attrGroupId.toString());
            for (String attrId : collectAttrIds) {
                SkuItemVo.SpuBaseAttrVo attrVo = new SkuItemVo.SpuBaseAttrVo();
                String attrValue = attrValueMap.get(attrId);
                String attrName = attrNameMap.get(attrId);
                attrVo.setAttrValue(attrValue);
                attrVo.setAttrName(attrName);
                attrVos.add(attrVo);
            }
            attrGroupVo.setAttrs(attrVos);
            return attrGroupVo;
        }).collect(Collectors.toList());
        return spuItemAttrGroupVos;
    }
}